{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit ThemeDescriptor;

interface

uses Classes, SysUtils, Logging, Descriptor;

const
  FILE_THEME_DESCRIPTOR = 'ThemeDescriptor.xml';

  // Default values for theme descriptor
  DEF_AUTHOR = 'No author';
  DEF_HOMEPAGE = 'http://www.athomemedia.co.uk';
  DEF_DES_WIDTH = 800;
  DEF_DES_HEIGHT = 600;
  DEF_LICENSE = 'No license details';
  DEF_DESCRIPTION = 'No description provided';
  DEF_DETAILS = 'No details provided';
  DEF_MIN_VER = '1.3.0';

type
  TAHMPreview = class
  private
    FName: String;
    FURL: String;
  protected
  public
    property Name: String read FName write FName;
    property URL: String read FURL write FURL;
  end;

  TAHMPreviewList = class
  private
    FList: TList;
  protected
    procedure Clear;
    function GetCount: Integer;
    function GetPreview(Index: Integer): TAHMPreview;
  public
    constructor Create;
    destructor Destroy; override;
    property Count: Integer read GetCount;
    property Previews[Index: Integer]: TAHMPreview read GetPreview;
    procedure AddPreview(Name, URL: String);
    procedure SaveAsXML(Lines: TStrings);
  end;

  TAHMThemeDescriptor = class(TAHMDescriptor)
  private
    FVersion: String;
    FDirectory: String;
    FAuthor: String;
    FHomepage: String;
    FCreated: TDateTime;
    FUpdated: TDateTime;
    FWidth: Integer;
    FHeight: Integer;
    FLicense: String;
    FDetails: String;
    FMinVersion: String;
    FPreviewList: TAHMPreviewList;
  protected
    procedure ResetDefaults; override;
    procedure ParsePreviewList;
    procedure ParseXML; override;
    procedure SaveXMLRoot(Lines: TStrings); override;
    procedure SaveAsXML(Lines: TStrings); override;
  public
    constructor Create; override;
    destructor Destroy; override;
    property Version: String read FVersion write FVersion;
    property Directory: String read FDirectory write FDirectory;
    property Author: String read FAuthor write FAuthor;
    property Homepage: String read FHomepage write FHomepage;
    property Created: TDateTime read FCreated write FCreated;
    property Updated: TDateTime read FUpdated write FUpdated;
    property DesignedWidth: Integer read FWidth write FWidth;
    property DesignedHeight: Integer read FHeight write FHeight;
    property License: String read FLicense write FLicense;
    property Details: String read FDetails write FDetails;
    property MinVersion: String read FMinVersion write FMinVersion;
    property PreviewList: TAHMPreviewList read FPreviewList;
  end;

implementation

uses TagNames, XMLTags, ErrorCodes, XMLHelper;

//----------------------------------------------------------------------------//

constructor TAHMPreviewList.Create;
begin
  inherited Create;

  FList := TList.Create;
end;

destructor TAHMPreviewList.Destroy;
begin
  Clear;
  FList.Free;

  inherited Destroy;
end;

procedure TAHMPreviewList.Clear;
var
  i: Integer;
begin
  for i := 0 to Pred(FList.Count) do
    TAHMPreview(FList[i]).Free;
  FList.Clear;
end;

function TAHMPreviewList.GetCount: Integer;
begin
  Result := FList.Count;
end;

function TAHMPreviewList.GetPreview(Index: Integer): TAHMPreview;
begin
  if (Index >= 0) and (Index < FList.Count) then
    Result := TAHMPreview(FList[Index])
  else
    Result := nil;
end;

procedure TAHMPreviewList.AddPreview(Name, URL: String);
var
  Preview: TAHMPreview;
begin
  // Create and add a new Preview object
  Preview := TAHMPreview.Create;
  Preview.Name := Name;
  Preview.URL := URL;

  FList.Add(Preview);
end;

procedure TAHMPreviewList.SaveAsXML(Lines: TStrings);
var
  i: Integer;
  Preview: TAHMPreview;
  sWork: String;
begin
  if FList.Count > 0 then
  begin
    Lines.Add(TABS[1] + TGB+TAG_PREVIEW_LIST+TGC);
    for i := 0 to Pred(FList.Count) do
    begin
      Preview := TAHMPreview(FList[i]);
      sWork := TGB+TAG_PREVIEW+SPC+ATTR_NAME+ATB + EncodeXML(Preview.Name);
      sWork := sWork + ATC + EncodeXML(Preview.URL) + TGE+TAG_PREVIEW+TGC;
      Lines.Add(TABS[2] + sWork);
    end;
    Lines.Add(TABS[1] + TGE+TAG_PREVIEW_LIST+TGC);
  end;
end;

//----------------------------------------------------------------------------//

constructor TAHMThemeDescriptor.Create;
begin
  inherited Create;

  FFileName := FILE_THEME_DESCRIPTOR;
  FRootTagName := TAG_THEME_DESCRIPTOR;

  FPreviewList := TAHMPreviewList.Create;

  // Theme descriptors are not mandatory parts of the theme
  FMandatory := False;
end;

destructor TAHMThemeDescriptor.Destroy;
begin
  FPreviewList.Free;

  inherited Destroy;
end;

procedure TAHMThemeDescriptor.ResetDefaults;
begin
  // Default values for theme descriptor
  FName := '';
  FVersion := '';
  FDirectory := '';
  FAuthor := DEF_AUTHOR;
  FHomepage := DEF_HOMEPAGE;
  FCreated := Now;
  FUpdated := Now;
  FWidth := DEF_DES_WIDTH;
  FHeight := DEF_DES_HEIGHT;
  FLicense := DEF_LICENSE;
  FDescription := DEF_DESCRIPTION;
  FDetails := DEF_DETAILS;
  FMinVersion := DEF_MIN_VER;
end;

procedure TAHMThemeDescriptor.ParseXML;
var
  RootNode: TAHMXMLNode;
begin
  // Save our custom descriptor attributes
  FDirectory := FHelper.GetAttribute(ATTR_DIRECTORY);
  FVersion := FHelper.GetAttribute(ATTR_VERSION);

  // What nodes do we have here?
  RootNode := FHelper.CurrentNode;
  FParseNode := nil;

  while FHelper.NextElement(RootNode, FParseNode) do
  begin
    if FHelper.CurrentElement = TAG_AUTHOR then
      FAuthor := FHelper.GetValue
    else if FHelper.CurrentElement = TAG_HOMEPAGE then
      FHomepage := FHelper.GetValue
    else if FHelper.CurrentElement = TAG_DATE_CREATED then
      FCreated := StrToDateDef(FHelper.GetValue, FCreated)
    else if FHelper.CurrentElement = TAG_DATE_UPDATED then
      FUpdated := StrToDateDef(FHelper.GetValue, FUpdated)
    else if FHelper.CurrentElement = TAG_DES_WIDTH then
      FWidth := StrToIntDef(FHelper.GetValue, FWidth)
    else if FHelper.CurrentElement = TAG_DES_HEIGHT then
      FHeight := StrToIntDef(FHelper.GetValue, FHeight)
    else if FHelper.CurrentElement = TAG_LICENSE then
      FLicense := FHelper.GetValue
    else if FHelper.CurrentElement = TAG_DESCRIPTION then
      FDescription := FHelper.GetValue
    else if FHelper.CurrentElement = TAG_DETAILS then
      FDetails := FHelper.GetValue
    else if FHelper.CurrentElement = TAG_MIN_VERSION then
      FMinVersion := FHelper.GetValue
    else if FHelper.CurrentElement = TAG_PREVIEW_LIST then
      ParsePreviewList
    else
      LogParsingError(THM_PRS_THM_FOUND_UNKNOWN_CONTENT_TAG);
  end;
end;

procedure TAHMThemeDescriptor.SaveXMLRoot(Lines: TStrings);
var
  sWork: String;
begin
  // Build root tag with custom attributes
  sWork := TGB+TAG_THEME_DESCRIPTOR;
  if FName <> '' then sWork := sWork + SPC+ATTR_NAME+ATB + EncodeXML(FName) + ATQ;
  if FVersion <> '' then sWork := sWork + SPC+ATTR_VERSION+ATB + EncodeXML(FVersion) + ATQ;
  if FDirectory <> '' then sWork := sWork + SPC+ATTR_DIRECTORY+ATB + EncodeXML(FDirectory) + ATQ;
  Lines.Add(sWork + TGC);
end;

procedure TAHMThemeDescriptor.SaveAsXML(Lines: TStrings);
begin
  // Write all theme descriptor lists & content to XML file
  Lines.Add(TABS[1]+TGB+TAG_AUTHOR+TGC + EncodeXML(FAuthor) + TGE+TAG_AUTHOR+TGC);
  Lines.Add(TABS[1]+TGB+TAG_HOMEPAGE+TGC + EncodeXML(FHomepage) + TGE+TAG_HOMEPAGE+TGC);
  Lines.Add(TABS[1]+TGB+TAG_DATE_CREATED+TGC + DateToStr(FCreated) + TGE+TAG_DATE_CREATED+TGC);
  Lines.Add(TABS[1]+TGB+TAG_DATE_UPDATED+TGC + DateToStr(FUpdated) + TGE+TAG_DATE_UPDATED+TGC);
  Lines.Add(TABS[1]+TGB+TAG_DES_WIDTH+TGC + IntToStr(FWidth) + TGE+TAG_DES_WIDTH+TGC);
  Lines.Add(TABS[1]+TGB+TAG_DES_HEIGHT+TGC + IntToStr(FHeight) + TGE+TAG_DES_HEIGHT+TGC);
  Lines.Add(TABS[1]+TGB+TAG_LICENSE+TGC + EncodeXML(FLicense) + TGE+TAG_LICENSE+TGC);
  Lines.Add(TABS[1]+TGB+TAG_DESCRIPTION+TGC + EncodeXML(FDescription) + TGE+TAG_DESCRIPTION+TGC);
  Lines.Add(TABS[1]+TGB+TAG_DETAILS+TGC + EncodeXML(FDetails) + TGE+TAG_DETAILS+TGC);
  Lines.Add(TABS[1]+TGB+TAG_MIN_VERSION+TGC + EncodeXML(FMinVersion) + TGE+TAG_MIN_VERSION+TGC);
  FPreviewList.SaveAsXML(Lines);
end;

procedure TAHMThemeDescriptor.ParsePreviewList;
var
  sName, sURL: String;
  PreviewNode: TAHMXMLNode;
begin
  // Keep going as long as we find previews to process
  PreviewNode := nil;
  while FHelper.FindElement(FParseNode, PreviewNode, TAG_PREVIEW) do
  begin
    sName := FHelper.GetAttribute(ATTR_NAME);
    sURL := FHelper.GetValue;

    // Add a new preview object
    FPreviewList.AddPreview(sName, sURL);
  end;
end;


end.
